package ru.ksu.environment;

import universum.bi.Location;
import universum.engine.environment.IAvailableMessage;
import universum.engine.environment.IBroadcastingParams;
import universum.engine.environment.IEnvControlMessage;
import universum.engine.environment.IEnvironment;

import java.util.ArrayList;
import java.util.List;

public class WideEnvironment implements IEnvironment {
    //private Map<Location, IEnvControlMessage> _messages = new HashMap<Location , IEnvControlMessage >();
    private final List<MsgContainer> _messages = new ArrayList<MsgContainer>();
    private int _curRoundNum;

    private class MsgContainer
    {
        public MsgContainer(IEnvControlMessage message, int roundNumber, int authorID)
        {
            Message = message ;
            RoundNumber = roundNumber;
            Recipients.add(authorID);
        }
        public IEnvControlMessage Message;
        public int RoundNumber;
        public List<Integer> Recipients = new ArrayList<Integer>();
    }
    public String getName() {
        return "Wide Environment";
    }
    public String getShortName()
    {
        return "wideenvironment";
    }
    public int getVersion() {
        return 0;
    }

    public synchronized void addMessage(IEnvControlMessage msg, IBroadcastingParams params) {
        synchronized (_messages) {
            _messages.add(new MsgContainer(msg,  _curRoundNum, msg.getAuthorID()));
        }
    }

    public synchronized List<IAvailableMessage> getMessages(Location pos, int callerID) {
        List<IAvailableMessage> result = new ArrayList<IAvailableMessage>();
        synchronized (new Object()) {
            for (MsgContainer msg : _messages) {
                if (!msg.Recipients.contains(callerID))
                {
                    msg.Recipients.add(callerID);
                    result.add(msg.Message.getPreview());
                }
            }
        }
        return result;
    }
    public void preRound(int roundNumber)
    {
        _curRoundNum = roundNumber;
    }
    public void postRound()
    {
        synchronized(_messages)
        {
            int i = 0;
            while (i < _messages.size())
            {
                MsgContainer msg = _messages.get(i);
                if (_curRoundNum - msg.RoundNumber > 2) _messages.remove(msg);
                else i++;
            }
        }
        //ioUtility.getInstance().writeDebug("WideEnv: messages count = " + _messages.size() + " after " + _curRoundNum + " round");
    }
}